#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>  // tasklet API
#include <linux/timer.h>

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Tasklet Example");

static struct tasklet_struct my_tasklet;
static struct timer_list my_timer;

// 1、Tasklet 执行函数（不能睡眠）
static void my_tasklet_func(unsigned long data)
{
    printk(KERN_INFO "Tasklet executed! Data: %lu, jiffies: %lu\n", data, jiffies);
}

//2、 定时器模拟中断，触发 Tasklet 调用
static void my_timer_func(struct timer_list *t)
{
    printk(KERN_INFO "Timer fired! Scheduling tasklet...\n");

    // 调用 tasklet_schedule 安排 tasklet 执行
    tasklet_schedule(&my_tasklet);

    // 重新激活定时器
    mod_timer(&my_timer, jiffies + msecs_to_jiffies(3000));
}

static int __init tasklet_module_init(void)
{
    printk(KERN_INFO "Tasklet Module Loaded\n");

    // 初始化 Tasklet（绑定处理函数和数据）
    tasklet_init(&my_tasklet, my_tasklet_func, 12345);

    // 初始化定时器
    timer_setup(&my_timer, my_timer_func, 0);
    mod_timer(&my_timer, jiffies + msecs_to_jiffies(3000));

    return 0;
}

static void __exit tasklet_module_exit(void)
{
    printk(KERN_INFO "Tasklet Module Unloaded\n");

    // 删除定时器，停止调度
    del_timer_sync(&my_timer);

    // 销毁 Tasklet（等待执行完成）
    tasklet_kill(&my_tasklet);
}

module_init(tasklet_module_init);
module_exit(tasklet_module_exit);
